home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / CodeCenter.c < prev    next >
Text File  |  1994-12-03  |  9KB  |  289 lines

  1. /* CodeCenter.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "CodeCenter.h"
  31. #include "Array.h"
  32. #include "Memory.h"
  33. #include "FunctionCode.h"
  34. #include "PcodeObject.h"
  35. #include "DataMunging.h"
  36.  
  37.  
  38. typedef struct
  39.     {
  40.         void*                            Signature;
  41.         FuncCodeRec*            Function;
  42.     } CodeEntryRec;
  43.  
  44.  
  45. struct CodeCenterRec
  46.     {
  47.         ArrayRec*                    CodeList; /* array of CodeEntryRec's */
  48.     };
  49.  
  50.  
  51. /* create new object code storage database */
  52. CodeCenterRec*            NewCodeCenter(void)
  53.     {
  54.         CodeCenterRec*        CodeCenter;
  55.  
  56.         CodeCenter = (CodeCenterRec*)AllocPtrCanFail(sizeof(CodeCenterRec),"CodeCenterRec");
  57.         if (CodeCenter == NIL)
  58.             {
  59.              FailurePoint1:
  60.                 return NIL;
  61.             }
  62.         CodeCenter->CodeList = NewArray();
  63.         if (CodeCenter->CodeList == NIL)
  64.             {
  65.              FailurePoint2:
  66.                 ReleasePtr((char*)CodeCenter);
  67.                 goto FailurePoint1;
  68.             }
  69.         return CodeCenter;
  70.     }
  71.  
  72.  
  73. /* delete object code database and all objects in it */
  74. void                                DisposeCodeCenter(CodeCenterRec* CodeCenter)
  75.     {
  76.         long                            Scan;
  77.         long                            Limit;
  78.  
  79.         CheckPtrExistence(CodeCenter);
  80.         Limit = ArrayGetLength(CodeCenter->CodeList);
  81.         for (Scan = 0; Scan < Limit; Scan += 1)
  82.             {
  83.                 CodeEntryRec*            CodeRecord;
  84.  
  85.                 CodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  86.                 DisposeFunction(CodeRecord->Function);
  87.                 ReleasePtr((char*)CodeRecord);
  88.             }
  89.         DisposeArray(CodeCenter->CodeList);
  90.         ReleasePtr((char*)CodeCenter);
  91.     }
  92.  
  93.  
  94. /* if we have the pcode, but not the function, then find it */
  95. /* it returns NIL if the function couldn't be found. */
  96. struct FuncCodeRec*    GetFunctionFromOpcode(CodeCenterRec* CodeCenter,
  97.                                             union OpcodeRec* Opcode)
  98.     {
  99.         long                            Limit;
  100.         long                            Scan;
  101.  
  102.         CheckPtrExistence(CodeCenter);
  103.         Limit = ArrayGetLength(CodeCenter->CodeList);
  104.         for (Scan = 0; Scan < Limit; Scan += 1)
  105.             {
  106.                 CodeEntryRec*            CodeRecord;
  107.  
  108.                 CodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  109.                 if (GetOpcodeFromPcode(GetFunctionPcode(CodeRecord->Function)) == Opcode)
  110.                     {
  111.                         return CodeRecord->Function;
  112.                     }
  113.             }
  114.         return NIL;
  115.     }
  116.  
  117.  
  118. /* obtain a handle for the named function */
  119. struct FuncCodeRec*    ObtainFunctionHandle(CodeCenterRec* CodeCenter, char* FunctionName,
  120.                                             long FuncNameLength)
  121.     {
  122.         long                            Limit;
  123.         long                            Scan;
  124.  
  125.         CheckPtrExistence(CodeCenter);
  126.         Limit = ArrayGetLength(CodeCenter->CodeList);
  127.         for (Scan = 0; Scan < Limit; Scan += 1)
  128.             {
  129.                 CodeEntryRec*            CodeRecord;
  130.                 char*                            LocalFunctionName;
  131.  
  132.                 CodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  133.                 LocalFunctionName = GetFunctionName(CodeRecord->Function);
  134.                 if (PtrSize(LocalFunctionName) == FuncNameLength)
  135.                     {
  136.                         if (MemEqu(LocalFunctionName,FunctionName,FuncNameLength))
  137.                             {
  138.                                 return CodeRecord->Function;
  139.                             }
  140.                     }
  141.             }
  142.         return NIL;
  143.     }
  144.  
  145.  
  146. /* find out how many functions are known by the code center */
  147. long                                CodeCenterGetNumFunctions(CodeCenterRec* CodeCenter)
  148.     {
  149.         CheckPtrExistence(CodeCenter);
  150.         return ArrayGetLength(CodeCenter->CodeList);
  151.     }
  152.  
  153.  
  154. /* delete all object code from a particular code module & delink references */
  155. void                                FlushModulesCompiledFunctions(CodeCenterRec* CodeCenter,
  156.                                             void* Signature)
  157.     {
  158.         long                            Scan;
  159.         long                            Limit;
  160.  
  161.         CheckPtrExistence(CodeCenter);
  162.         Limit = ArrayGetLength(CodeCenter->CodeList);
  163.         Scan = 0;
  164.         while (Scan < Limit)
  165.             {
  166.                 CodeEntryRec*            CodeRecord;
  167.  
  168.                 CodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  169.                 if (CodeRecord->Signature == Signature)
  170.                     {
  171.                         long                            Index;
  172.  
  173.                         /* unlink references to this function */
  174.                         for (Index = 0; Index < Limit; Index += 1)
  175.                             {
  176.                                 CodeEntryRec*            OtherCodeRecord;
  177.  
  178.                                 OtherCodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,
  179.                                     Index);
  180.                                 PcodeUnlink(GetFunctionPcode(OtherCodeRecord->Function),
  181.                                     GetFunctionName(CodeRecord->Function),
  182.                                     GetFunctionPcode(CodeRecord->Function));
  183.                             }
  184.                         /* delete storage occupied by this function */
  185.                         DisposeFunction(CodeRecord->Function);
  186.                         ReleasePtr((char*)CodeRecord);
  187.                         /* delete the function from the array & adjust Limit (local array size) */
  188.                         ArrayDeleteElement(CodeCenter->CodeList,Scan);
  189.                         Limit -= 1;
  190.                     }
  191.                  else
  192.                     {
  193.                         Scan += 1;
  194.                     }
  195.             }
  196.     }
  197.  
  198.  
  199. /* get a list of functions owned by a specified code module */
  200. struct ArrayRec*        GetListOfFunctionsForModule(CodeCenterRec* CodeCenter,
  201.                                             void* Signature)
  202.     {
  203.         long                            Scan;
  204.         long                            Limit;
  205.         ArrayRec*                    List;
  206.  
  207.         CheckPtrExistence(CodeCenter);
  208.         List = NewArray();
  209.         if (List == NIL)
  210.             {
  211.              FailurePoint1:
  212.                 return NIL;
  213.             }
  214.         Limit = ArrayGetLength(CodeCenter->CodeList);
  215.         for (Scan = 0; Scan < Limit; Scan += 1)
  216.             {
  217.                 CodeEntryRec*            CodeRecord;
  218.  
  219.                 CodeRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  220.                 if (CodeRecord->Signature == Signature)
  221.                     {
  222.                         if (!ArrayAppendElement(List,CodeRecord->Function))
  223.                             {
  224.                                 DisposeArray(List);
  225.                                 goto FailurePoint1;
  226.                             }
  227.                     }
  228.             }
  229.         return List;
  230.     }
  231.  
  232.  
  233. /* find out if a function with the given name exists */
  234. MyBoolean                        CodeCenterHaveThisFunction(CodeCenterRec* CodeCenter,
  235.                                             char* FunctionName, long FuncNameLength)
  236.     {
  237.         long                            Scan;
  238.         long                            Limit;
  239.  
  240.         CheckPtrExistence(CodeCenter);
  241.         Limit = ArrayGetLength(CodeCenter->CodeList);
  242.         for (Scan = 0; Scan < Limit; Scan += 1)
  243.             {
  244.                 CodeEntryRec*            FuncRecord;
  245.                 char*                            TestFuncName;
  246.  
  247.                 FuncRecord = (CodeEntryRec*)ArrayGetElement(CodeCenter->CodeList,Scan);
  248.                 TestFuncName = GetFunctionName(FuncRecord->Function);
  249.                 if (PtrSize(TestFuncName) == FuncNameLength)
  250.                     {
  251.                         if (MemEqu(FunctionName,TestFuncName,FuncNameLength))
  252.                             {
  253.                                 /* yup, function's been added before */
  254.                                 return True;
  255.                             }
  256.                     }
  257.             }
  258.         return False;
  259.     }
  260.  
  261.  
  262. /* add this function to the code center.  it better not be in there already */
  263. MyBoolean                        AddFunctionToCodeCenter(CodeCenterRec* CodeCenter,
  264.                                             struct FuncCodeRec* TheNewFunction, void* Signature)
  265.     {
  266.         CodeEntryRec*            FuncRecord;
  267.  
  268.         CheckPtrExistence(CodeCenter);
  269.         CheckPtrExistence(TheNewFunction);
  270.         ERROR(CodeCenterHaveThisFunction(CodeCenter,GetFunctionName(TheNewFunction),
  271.             PtrSize(GetFunctionName(TheNewFunction))),PRERR(ForceAbort,
  272.             "AddFunctionToCodeCenter:  function is already in the database"));
  273.         FuncRecord = (CodeEntryRec*)AllocPtrCanFail(sizeof(CodeEntryRec),"CodeEntryRec");
  274.         if (FuncRecord == NIL)
  275.             {
  276.              FailurePoint1:
  277.                 return False;
  278.             }
  279.         FuncRecord->Signature = Signature;
  280.         FuncRecord->Function = TheNewFunction;
  281.         if (!ArrayAppendElement(CodeCenter->CodeList,FuncRecord))
  282.             {
  283.              FailurePoint2:
  284.                 ReleasePtr((char*)FuncRecord);
  285.                 goto FailurePoint1;
  286.             }
  287.         return True;
  288.     }
  289.